home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 18 / CU Amiga Magazine's Super CD-ROM 18 (1997)(EMAP Images)(GB)[!][issue 1998-01].iso / CUCD / Programming / AmigaE / Src / Gfx / Chunky3d / ls_sculpt.e < prev    next >
Encoding:
Text File  |  1995-12-19  |  5.6 KB  |  206 lines

  1. /*
  2. +---------------------------------------------------------------+
  3. |    RealTime 2.5d Landscape Sculpting !            |
  4. +---------------------------------------------------------------+
  5.  
  6. usage: run it, preferably selecting lowres from the requester,
  7. the sculpt with leftmouse, quit with rightmouse.
  8.  
  9. sculpting is done as follows: two halfs of the screen (left-right)
  10. influence the height of the two sides of the landscape. You'll need
  11. to experiment a bit to get an idea what you can accomplish this way.
  12.  
  13. for further fun: try and recompile with a different #define for
  14. `trans()' further down the source.
  15.  
  16. The code is pretty OS friendly (using intuition double-buffering
  17. etc.), I hope it also works on gfx-cards (don't know about the
  18. chunky code though).
  19.  
  20. The sculpting bit is only a demo for the underlying engine, which
  21. could display _any_ animated 3d landscape in realtime [it
  22. should be fast enough on anything from an A1200+fast upwards]
  23.  
  24. */
  25.  
  26. OPT OSVERSION=39, PREPROCESS
  27.  
  28. CONST CWIDTH=256,CHEIGHT=128,CWSHIFT=8
  29. CONST SCHEIGHT=CHEIGHT+20
  30. CONST TEMPBUFS=CWIDTH*CHEIGHT/2,BUFS=CWIDTH*CHEIGHT,BUFM=$7FFF
  31. CONST SXOFF=50,SYOFF=80
  32. CONST XY3D=80
  33.  
  34. MODULE '*c2p4', '*screenmodereq_db', 'tools/exceptions', 'tools/scrbuffer',
  35.        'intuition/screens', 'graphics/rastport', 'graphics/gfx',
  36.        'intuition/intuition', 'devices/inputevent'
  37.  
  38. DEF sideh[XY3D]:ARRAY OF LONG, both[XY3D]:ARRAY OF LONG
  39.  
  40. PROC main() HANDLE
  41.   DEF dbs,scr=NIL:PTR TO screen,bm:PTR TO bitmap,win=NIL:PTR TO window,
  42.       tbuf2,tbuf3,tbuf2b,tbuf3b,cbuf,dbuf,dbuf2,lsbuf,sigbit,sig,safe=TRUE,a,x=0,y=0,
  43.       imsg:PTR TO intuimessage,temp,lastx=-1,lasty=-1,quit=FALSE
  44.   IF (dbs:=openreqscreen(CWIDTH,SCHEIGHT,4,'2.5d'))=NIL THEN Raise()
  45.   scr:=sb_GetScreen(dbs)
  46.   IF (win:=OpenW(0,0,CWIDTH-1,SCHEIGHT-1,
  47.     IDCMP_MOUSEBUTTONS OR IDCMP_MOUSEMOVE,
  48.     WFLG_REPORTMOUSE OR WFLG_BORDERLESS OR WFLG_SIMPLE_REFRESH OR WFLG_BACKDROP OR WFLG_ACTIVATE OR WFLG_RMBTRAP,
  49.     '',scr,15,NIL))=NIL THEN Raise("WIN")
  50.   tbuf2:=NewM(TEMPBUFS+TEMPBUFS,2)
  51.   tbuf3:=tbuf2+TEMPBUFS
  52.   tbuf2b:=NewM(TEMPBUFS+TEMPBUFS,2)
  53.   tbuf3b:=tbuf2b+TEMPBUFS
  54.   NEW cbuf[BUFS]
  55.   NEW dbuf[BUFS]
  56.   NEW dbuf2[BUFS]
  57.   NEW lsbuf[BUFS]
  58.   FOR a:=0 TO BUFS-1
  59.     dbuf[a]:=-1
  60.     dbuf2[a]:=-1
  61.   ENDFOR
  62.   FOR a:=0 TO XY3D-1
  63.     sideh[a]:=15
  64.     both[a]:=15
  65.   ENDFOR
  66.   ->FOR a:=0 TO 15 DO SetColour(scr,15-a,a*16,(15-a)*16,240)
  67.   FOR a:=0 TO 15 DO SetColour(scr,15-a,a*16,a*16,a*16)
  68.   FOR a:=0 TO BUFS-1 DO cbuf[a]:=15
  69.   CopyMem(cbuf,lsbuf,BUFS)
  70.   SetRast(scr.rastport,0)
  71.   IF (sigbit:=AllocSignal(-1))<>-1
  72.     sig:=Shl(1,sigbit)
  73.     REPEAT
  74.       render(cbuf,lsbuf,0,XY3D,XY3D)
  75.       IF safe=FALSE
  76.         Wait(sig)
  77.         safe:=TRUE
  78.       ENDIF
  79.       bm:=sb_NextBuffer(dbs)
  80.       c2p4(tbuf3,tbuf2,cbuf,dbuf,bm.planes,FindTask(NIL),sig,gfxbase)
  81.       temp:=dbuf; dbuf:=dbuf2; dbuf2:=temp
  82.       temp:=tbuf2; tbuf2:=tbuf2b; tbuf2b:=temp
  83.       temp:=tbuf3; tbuf3:=tbuf3b; tbuf3b:=temp
  84.       WHILE imsg:=GetMsg(win.userport)
  85.         x:=imsg.mousex; y:=imsg.mousey
  86.         IF imsg.qualifier AND IEQUALIFIER_RBUTTON THEN quit:=TRUE
  87.         IF (imsg.class=IDCMP_MOUSEBUTTONS) AND (imsg.code=SELECTUP)
  88.           lastx:=-1; lasty:=-1
  89.         ENDIF
  90.         IF imsg.qualifier AND IEQUALIFIER_LEFTBUTTON
  91.           IF lastx>=0
  92.             WHILE lastx<>x
  93.               IF lastx>x THEN lastx-- ELSE lastx++
  94.               press(lastx,y,lsbuf)
  95.             ENDWHILE
  96.           ELSE
  97.             press(lastx:=x,lasty:=y,lsbuf)
  98.           ENDIF
  99.         ENDIF
  100.         ReplyMsg(imsg)
  101.       ENDWHILE
  102.       safe:=FALSE
  103.     UNTIL quit
  104.     IF safe=FALSE THEN Wait(sig)
  105.     FreeSignal(sigbit)
  106.   ENDIF
  107. EXCEPT DO
  108.   IF win THEN CloseWindow(win)
  109.   closereqscreen(dbs)
  110.   SELECT exception
  111.     CASE "SCR"; WriteF('no screen!\n')
  112.     CASE "REQ"; WriteF('Error: Could not allocate ASL request\n')
  113.     CASE "ASL"; WriteF('Error: Could not open ASL library\n')
  114.   ENDSELECT
  115.   report_exception()
  116. ENDPROC
  117.  
  118. PROC press(mx,my,buf)
  119.   DEF height,xc,lr
  120.   mx:=Bounds(mx,0,CWIDTH-1)
  121.   my:=Bounds(my,0,SCHEIGHT-1)
  122.   height:=my*16/SCHEIGHT
  123.   xc,lr:=Mod(mx,CWIDTH/2)
  124.   xc:=xc*XY3D*2/CWIDTH
  125.   IF lr THEN side_sculpt(XY3D-1-xc,buf,height) ELSE bot_sculpt(xc,buf,height)
  126. ENDPROC
  127.  
  128. #define trans(a,b) a + b / 2
  129. ->#define trans(a,b) Eor(a,b)
  130. ->#define trans(a,b) Max(a,b)
  131. ->#define trans(a,b) Min(a,b)
  132.  
  133. PROC bot_sculpt(off,buf,h)
  134.   DEF p,a,sh:PTR TO LONG
  135.   p:=off+buf
  136.   both[off]:=h
  137.   sh:=sideh
  138.   FOR a:=0 TO XY3D-1
  139.     p[]:=trans(sh[]++,h)
  140.     p:=p+CWIDTH
  141.   ENDFOR
  142. ENDPROC
  143.  
  144. PROC side_sculpt(off,buf,h)
  145.   DEF p,a,bh:PTR TO LONG
  146.   p:=off*CWIDTH+buf
  147.   sideh[off]:=h
  148.   bh:=both
  149.   FOR a:=0 TO XY3D-1 DO p[]++:=trans(bh[]++,h)
  150. ENDPROC
  151.  
  152. PROC render(destbuf,lsbuf,offs,xs,ys)
  153.   DEF a,t1,t2
  154.   clearmem(destbuf,BUFS)
  155.   t1:=ys-1*CWIDTH-1+offs
  156.   t2:=xs-1+offs
  157.   FOR a:=1 TO xs DO line(a,t1+a AND BUFM,a+SXOFF,a/2+SYOFF,destbuf,lsbuf)
  158.   FOR a:=ys-1 TO 1 STEP -1 DO line(a,a-1*CWIDTH+t2 AND BUFM,xs*2+SXOFF-a,a/2+SYOFF,destbuf,lsbuf)
  159. ENDPROC
  160.  
  161. PROC clearmem(mem,size)
  162.   DEF e:REG,a:REG,b:REG,c:REG,d:REG
  163.   e:=size/16-1
  164.   a:=b:=c:=d:=$04040404
  165.   MOVE.L mem,A0
  166.   ADD.L size,A0
  167. clloop:
  168.   MOVEM.L a/b/c/d,-(A0)
  169.   DBRA e,clloop
  170. ENDPROC
  171.  
  172. PROC line(num,start,sx,sy,destbuf,lsbuf)
  173.   DEF a:REG,y,t:REG,c=0:REG,xoff:REG,yoff:REG
  174.   xoff:=sx+destbuf
  175.   yoff:=sy-25-num+1
  176.   y:=sy*CWIDTH+xoff
  177.   a:=num-1+yoff
  178.   MOVE.L start,D2        -> D2=start
  179.   MOVEA.L lsbuf,A3        -> A3=lsbuf
  180.   MOVE.L y,A2            -> A2=y
  181.   MOVE.L #CWIDTH,D1        -> D1=CWIDTH
  182.   MOVE.L #BUFM,D0        -> D0=BUFM
  183.   MOVE.L #CWIDTH+1,A1        -> A1=CWIDTH+1
  184. bloop:                -> this loop eats most cpu-time.
  185.   MOVE.B 0(A3,D2.L),c
  186.   MOVE.L a,t
  187.   ADD.L c,t
  188.   LSL.L #CWSHIFT,t
  189.   ADD.L xoff,t
  190.   CMP.L A2,t
  191.   BGE.S skip
  192.   BRA.S loop
  193. begi:
  194.   SUBA.L D1,A2
  195.   MOVE.B c,(A2)
  196. loop:
  197.   CMP.L A2,t
  198.   BMI.S begi
  199. skip:
  200.   SUB.L A1,D2
  201.   AND.L D0,D2
  202.   SUBQ.L #1,a
  203.   CMP.L yoff,a
  204.   BPL.S bloop
  205. ENDPROC
  206.